#include <vector>
#include <fstream>
#include <iostream>

using namespace std;

struct Point {
  int x;
  int y;
};

struct Rect {
  // 属性
  Point bl;
  Point tr;
  
  // 方法
  // 判断 pt 表达的点是否在由 bl 和 tr 表达的矩形里
  bool covered(Point pt) {
    return (pt.x >= bl.x && pt.y >= bl.y) && (pt.x <= tr.x && pt.y <= tr.y);
  }

  int area() {
    return (tr.y - bl.y) * (tr.x - bl.x);
  }
};

int main(int argc, char *argv[]) {
  
  int x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0, x4 = 0, y4 = 0;
  
  ifstream ifs("BlockedBillboard.in");
  
  ifs >> x1 >> y1 >> x2 >> y2;
  ifs >> x3 >> y3 >> x4 >> y4;
  
  // Four corners of the lawnmower billboard
  Point tl { x1, y2 };
  Point bl { x1, y1 };
  Point tr { x2, y2 };
  Point br { x2, y1 };
  
  Rect lawnmowerRect {
    {x1, y1},
    {x2, y2}
  };

  Rect foodRect {
    {x3, y3},
    {x4, y4}
  };

  int cornersCovered = 0;
  
  if (foodRect.covered(tl)) { ++cornersCovered; }
  if (foodRect.covered(bl)) { ++cornersCovered; }
  if (foodRect.covered(tr)) { ++cornersCovered; }
  if (foodRect.covered(br)) { ++cornersCovered; }
  
  int area = 0;
  cout<<cornersCovered<<endl;
  if (cornersCovered < 2) {
    area = lawnmowerRect.area();
  }
  else if (cornersCovered >= 2 && cornersCovered <= 3) {
    Rect covered {
      Point {
        max(lawnmowerRect.bl.x, foodRect.bl.x),
        max(lawnmowerRect.bl.y, foodRect.bl.y)
      },
      Point {
        min(lawnmowerRect.tr.x, foodRect.tr.x),
        min(lawnmowerRect.tr.y, foodRect.tr.y)
      }
    };
    
    area = lawnmowerRect.area() - covered.area();
  }
  
  ofstream ofs("BlockedBillboard.out");
  
  ofs << area;
  
  return 0;
}